<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        const PENDING = 'pending';
        const FULFILLED = 'fulfilled';
        const REJECTED = 'rejected';
        class myPromise {
            constructor(executor) {
                this.status = PENDING;
                this.value = undefined;
                this.reason = undefined;
                this.onResolvedCallbacks = [];
                this.onRejectedCallbacks = [];
                const resolve = (value) => {
                    if (this.status === PENDING) {
                        this.status = FULFILLED;
                        this.value = value;
                        this.onResolvedCallbacks.forEach(fn => fn());
                    }
                }
                const reject = (reason) => {
                    if (this.status === PENDING) {
                        this.status = REJECTED;
                        this.reason = reason;
                        this.onRejectedCallbacks.forEach(fn => fn());
                    }
                }
                try {
                    executor(resolve, reject);
                } catch (error) {
                    reject(error);
                }
            }

            then(onFulfilled, onRejected) {
                onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
                onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason };
                let promise2 = new Promise((resolve, reject) => {
                    if (this.status === FULFILLED) {
                        setTimeout(() => {
                            try {
                                let x = onFulfilled(this.value);
                                resolvePromise(promise2, x, resolve, reject);
                            } catch (error) {
                                reject(error);
                            }
                        },0)
                    }
                    if (this.status === REJECTED) {
                        setTimeout(() => {
                            try {
                                let x = onRejected(this.reason);
                                resolvePromise(promise2, x, resolve, reject)
                            } catch (error) {
                                reject(error);
                            }
                        },0)
                    }
                    if (this.status === PENDING) {
                        this.onResolvedCallbacks.push(() => {
                            setTimeout(() => {
                                try {
                                    let x = onFulfilled(this.value);
                                    resolvePromise(promise2, x, resolve, reject);
                                } catch (error) {
                                    reject(error);
                                }
                            },0)
                        })
                        this.onRejectedCallbacks.push(() => {
                            setTimeout(() => {
                                try {
                                    let x = onRejected(this.reason);
                                    resolvePromise(promise2, x, resolve, reject)
                                } catch (error) {
                                    reject(error);
                                }
                            },0)
                        })
                    }
                })
                return promise2
            }
        }
        
    </script>
</body>
</html>